package com.ssy.lingxi.product.serviceImpl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.ssy.lingxi.common.constant.CommonConstant;
import com.ssy.lingxi.common.constant.member.MemberTypeEnum;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.platform.manage.api.feign.inner.AreaControllerFeign;
import com.ssy.lingxi.platform.manage.api.model.vo.area.AreaVO;
import com.ssy.lingxi.product.api.model.request.warehouse.*;
import com.ssy.lingxi.product.api.model.response.warehouse.WarehouseDetailsResponse;
import com.ssy.lingxi.product.api.model.response.warehouse.WarehouseResponse;
import com.ssy.lingxi.product.entity.commodity.Commodity;
import com.ssy.lingxi.product.entity.warehouse.FreightSpace;
import com.ssy.lingxi.product.entity.warehouse.Warehouse;
import com.ssy.lingxi.product.repository.warehouse.FreightSpaceRepository;
import com.ssy.lingxi.product.repository.warehouse.WarehouseRepository;
import com.ssy.lingxi.product.service.WarehouseService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 仓库管理
 * @author wrc
 * @date 2020/6/19
 */
@Service
public class WarehouseServiceImpl implements WarehouseService {
    @Resource
    AreaControllerFeign areaControllerFeign;
    @Resource
    WarehouseRepository warehouseRepository;
    @Resource
    FreightSpaceRepository freightSpaceRepository;

    /**
     * 查询仓库列表
     *
     * @param request
     * @author wrc
     * @date 2020/6/19
     */
    @Override
    public Wrapper<PageData<WarehouseResponse>> warehouseList(WarehouseRequest request, UserLoginCacheDTO sysUser) {
        String name = request.getName();
        Long memberId = sysUser.getMemberId();
        Long memberRoleId = sysUser.getMemberRoleId();
        Pageable page = PageRequest.of(request.getCurrent() - 1, request.getPageSize());
        Page<Warehouse> pageList;
        if(StringUtils.isNotBlank(name)){
            pageList = warehouseRepository.findByMemberIdAndMemberRoleIdAndNameContainingOrderByUpdateTimeDesc(memberId, memberRoleId, name, page);
        }else{
            pageList = warehouseRepository.findByMemberIdAndMemberRoleIdOrderByUpdateTimeDesc(memberId, memberRoleId, page);
        }
        Wrapper<List<AreaVO>> listWrapper = areaControllerFeign.areaList();
        List<WarehouseResponse> content = new ArrayList<>();
        if(ResponseCode.SUCCESS.getCode() == listWrapper.getCode()) {
            List<AreaVO> data = listWrapper.getData();
            Map<Long, AreaVO> map = data.stream().collect(Collectors.toMap(AreaVO::getId, AreaVO -> AreaVO));
            content = pageList.getContent().stream().map(warehouse -> {
                WarehouseResponse warehouseResponse = new WarehouseResponse();
                BeanUtils.copyProperties(warehouse, warehouseResponse);
                warehouseResponse.setAddress(map.get(warehouse.getProvinceId()).getName().concat(map.get(warehouse.getCityId()).getName().concat(map.get(warehouse.getAreaId()).getName().concat(Optional.ofNullable(map.get(warehouse.getStreetId())).map(AreaVO::getName).orElse("")).concat(null == warehouse.getAddress() ? "" : warehouse.getAddress()))));
                return warehouseResponse;
            }).collect(Collectors.toList());
        }
        return Wrapper.success(new PageData<>(pageList.getTotalElements(), content));
    }

    /**
     * 查询仓库详情
     *
     * @param request
     * @author wrc
     * @date 2020/8/5
     */
    @Override
    public Wrapper<WarehouseResponse> warehouseDetails(Long id) {
        Warehouse warehouse = warehouseRepository.findById(id).orElse(null);
        if(ObjectUtil.isNull(warehouse)){
            return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
        }
        WarehouseResponse warehouseResponse = new WarehouseResponse();
        BeanUtils.copyProperties(warehouse, warehouseResponse);
        return Wrapper.success(warehouseResponse);
    }

    /**
     * 查询全部仓库
     *
     * @author wrc
     * @date 2020/8/5
     */
    @Override
    public Wrapper<List<WarehouseResponse>> warehouseAll(UserLoginCacheDTO sysUser ) {
        Long memberId = sysUser.getMemberId();
        Long memberRoleId = sysUser.getMemberRoleId();
        List<Warehouse> list = warehouseRepository.findByMemberIdAndMemberRoleIdAndStateOrderByUpdateTimeDesc(memberId, memberRoleId, CommonConstant.State.STATE_START);
        Wrapper<List<AreaVO>> listWrapper = areaControllerFeign.areaList();
        List<WarehouseResponse> content = new ArrayList<>();
        if(ResponseCode.SUCCESS.getCode() == listWrapper.getCode()) {
            List<AreaVO> data = listWrapper.getData();
            Map<Long, AreaVO> map = data.stream().collect(Collectors.toMap(AreaVO::getId, AreaVO -> AreaVO));
            content = list.stream().map(warehouse -> {
                WarehouseResponse warehouseResponse = new WarehouseResponse();
                BeanUtils.copyProperties(warehouse, warehouseResponse);
                warehouseResponse.setAddress(map.get(warehouse.getProvinceId()).getName().concat(map.get(warehouse.getCityId()).getName().concat(map.get(warehouse.getAreaId()).getName().concat(Optional.ofNullable(map.get(warehouse.getStreetId())).map(AreaVO::getName).orElse("")).concat(null == warehouse.getAddress() ? "" : warehouse.getAddress()))));
                return warehouseResponse;
            }).collect(Collectors.toList());
        }
        return Wrapper.success(content);
    }

    /**
     * 添加仓库
     *
     * @author wrc
     * @date 2020/6/19
     */
    @Transactional
    @Override
    public Wrapper<Void> warehouseAddOrUpdate(WarehouseAddOrUpdateRequest request, UserLoginCacheDTO sysUser) {
        Warehouse warehouse = new Warehouse();
        if(ObjectUtil.isNotNull(request.getId())){
            warehouse = warehouseRepository.findById(request.getId()).orElse(null);
            if(ObjectUtil.isNull(warehouse)){
                return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
            }
            if(!CommonConstant.State.STATE_STOP.equals(warehouse.getState())){
                return Wrapper.fail(ResponseCode.INCORRECT_DATA_STATE_CANNOT_BE_UPDATE);
            }
        }else{
            warehouse.setMemberId(sysUser.getMemberId());
            warehouse.setMemberRoleId(sysUser.getMemberRoleId());
            warehouse.setCreateTime(System.currentTimeMillis());
            warehouse.setState(CommonConstant.State.STATE_START);
        }
        BeanUtils.copyProperties(request, warehouse);
        warehouse.setUpdateTime(System.currentTimeMillis());
        warehouseRepository.saveAndFlush(warehouse);
        return Wrapper.success();
    }

    /**
     * 删除仓库
     * @author wrc
     * @date 2020/6/19
     */
    @Override
    public Wrapper<Void> warehouseDelete(Long id) {
        Warehouse warehouse = warehouseRepository.findById(id).orElse(null);
        if(ObjectUtil.isNull(warehouse)){
            return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
        }
        if(!CommonConstant.State.STATE_STOP.equals(warehouse.getState())){
            return Wrapper.fail(ResponseCode.INCORRECT_DATA_STATE_CANNOT_BE_DELETED);
        }
        warehouseRepository.deleteById(id);
        return Wrapper.success();
    }

    /**
     * 停用启用
     * @author wrc
     * @date 2020/6/19
     */
    @Transactional
    @Override
    public Wrapper<Void> warehouseStartOrStop(WarehouseStartRoStopRequest request) {
        Warehouse warehouse = warehouseRepository.findById(request.getId()).orElse(null);
        if(ObjectUtil.isNull(warehouse)){
            return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
        }
        if(CommonConstant.State.STATE_STOP.equals(request.getState())){
            List<FreightSpace> allByWarehouseIdEquals = freightSpaceRepository.findAllByWarehouseIdEquals(warehouse.getId());
            if(CollectionUtil.isNotEmpty(allByWarehouseIdEquals)){
                return Wrapper.fail(ResponseCode.WAREHOUSE_NOT_STOP);
            }
        }
        warehouse.setState(request.getState());
        warehouse.setUpdateTime(System.currentTimeMillis());
        warehouseRepository.saveAndFlush(warehouse);
        return Wrapper.success();
    }
}
